// http.js
import Axios from "axios";
import NProgress from "../progress";
import { getToken } from "@/utils/auth";

const defaultConfig = {
  // 请求超时时间
  timeout: 10000,
  headers: {
    Accept: "application/json, text/plain, */*",
    "Content-Type": "application/json",
    "X-Requested-With": "XMLHttpRequest",
  },
};

class PureHttp {
  constructor() {
    this.httpInterceptorsRequest();
    this.httpInterceptorsResponse();
  }

  static axiosInstance = Axios.create(defaultConfig);

  /** 请求拦截 */
  httpInterceptorsRequest() {
    // .axiosInstance.interceptors.request.use 是 Axios 提供的一个方法，
    // 用于设置请求拦截器。请求拦截器允许你在请求发送到服务器之前对请求进行一些处理或修改。
    PureHttp.axiosInstance.interceptors.request.use(
      async (config) => {
        // 开启进度条动画
        NProgress.start();

        // 优先判断post/get等方法是否传入回调，否则执行初始化设置等回调
        if (typeof config.beforeRequestCallback === "function") {
          config.beforeRequestCallback(config);
          return config;
        }
        // if (PureHttp.initConfig.beforeRequestCallback) {
        //   PureHttp.initConfig.beforeRequestCallback(config);
        //   return config;
        // }

        /** 请求白名单，放置一些不需要token的接口（通过设置请求白名单，防止token过期后再请求造成的死循环问题） */
        const whiteList = ["/refresh-token", "/login"];
        if (whiteList.find((url) => url === config.url)) {
          return config;
        }

        return new Promise((resolve, reject) => {
          const data = getToken();
          if (data) {
          } else {
            resolve(config);
          }
        });
      },
      (error) => {
        return Promise.reject(error);
      }
    );
  }
  /** 响应拦截*/
  httpInterceptorsResponse() {
    PureHttp.axiosInstance.interceptors.response.use(
      (response) => {
        const $config = response.config;
        //关闭进度条
        NProgress.done();
        // 优先判断post/get等方法是否传入回调，否则执行初始化设置等回调
        if (typeof $config.beforeResponseCallback === "function") {
          $config.beforeResponseCallback(response);
          return response.data;
        }
        return response.data;
      },
      (error) => {
        const $error = error;
        $error.isCancelRequest = Axios.isCancel($error);
        // 关闭进度条动画
        NProgress.done();
        // 所有的响应异常 区分来源为取消请求/非取消请求
        return Promise.reject($error);
      }
    );
  }
  /** 通用请求工具函数 */
  request(method, url, param, axiosConfig) {
    const config = {
      method,
      url,
      ...param,
      ...axiosConfig,
    };

    // 单独处理自定义请求/响应回调
    return new Promise((resolve, reject) => {
      PureHttp.axiosInstance
        .request(config)
        .then((response) => {
          resolve(response);
        })
        .catch((error) => {
          reject(error);
        });
    });
  }
}

export const http = new PureHttp();
